﻿using System;
using System.Collections.Generic;
using System.IO;
using Autodesk.Revit.DB;
using FlexCell;
using YArchitech.Controls;
using YArchitech.Revit;
using YJKArchBaseCode.OutWallSearch;
using YJKMaterialStatistic;
using YJKRevitView;
using YJKPresentation.Utils;

namespace YJKWndrStatisticsExcel.AreaTable.DataManager
{
	internal class BuildingDetailList
	{
        public BuildingDetailList(Autodesk.Revit.DB.Document doc, ref FlexCell.Grid grid, GridSetCommonInfo gridSetInfo)
		{
			this.m_doc = doc;
			this.m_grid = grid;
			this.m_gridSetInfo = gridSetInfo;
		}

		public bool GetStatisticGrid()
		{
			this.StatisticData();
			this.m_grid.Locked = false;
			return this.SetDataToGrid();
		}

		private void StatisticData()
		{
			if (this.m_doc == null)
			{
				return;
			}
			this.GetBuildingInfoInDoc();
			if (this.m_gridSetInfo.LinkFile)
			{
				this.GetBuildingInfoInLinkDoc();
			}
		}

		private void GetBuildingInfoInDoc()
		{
			List<string> list = new List<string>();
			list.Add("");
			string text = this.m_doc.Title;
			text = Path.GetFileNameWithoutExtension(text);
			list.Add(text);
			List<ViewPlan> allFloorViewPlan = FloorSelectManager.GetAllFloorViewPlan(this.m_doc);
			List<ViewPlan> singleFloorViewPlan = this.GetSingleFloorViewPlan(this.m_doc, allFloorViewPlan);
			int num = 0;
			int num2 = 0;
			using (List<ViewPlan>.Enumerator enumerator = singleFloorViewPlan.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					if (Geometry.LessThan(enumerator.Current.GenLevel.Elevation, 0.0))
					{
						num2++;
					}
					else
					{
						num++;
					}
				}
			}
			string item;
			if (num2 > 0)
			{
				item = num.ToString() + "\\-" + num2.ToString();
			}
			else
			{
				item = num.ToString() + "\\" + num2.ToString();
			}
			list.Add(item);
			list.Add(this.GetBuildingHeight(this.m_doc).ToString("0.00"));
			List<ViewPlan> areaViewPlan = this.GetAreaViewPlan(this.m_doc);
			double num3 = 0.0;
			double num4 = 0.0;
			foreach (ViewPlan viewPlan in areaViewPlan)
			{
				if (Geometry.LessThan(viewPlan.GenLevel.Elevation, 0.0))
				{
					num4 += UnitConvert.AreaConverFromAPI(this.m_doc, this.GetAreaOfCurAreaViewPlan(this.m_doc, viewPlan));
				}
				else
				{
					num3 += UnitConvert.AreaConverFromAPI(this.m_doc, this.GetAreaOfCurAreaViewPlan(this.m_doc, viewPlan));
				}
			}
			list.Add(num3.ToString("0.00"));
			list.Add(num4.ToString("0.00"));
			list.Add((num3 + num4).ToString("0.00"));
			this.m_lstLstData.Add(list);
		}

		private void GetBuildingInfoInLinkDoc()
		{
			foreach (RevitLinkInstance revitLinkInstance in this.GetAllRevitLinkInstancesInDoc())
			{
				Document linkDocument = revitLinkInstance.GetLinkDocument();
				List<string> list = new List<string>();
				list.Add("");
				string text = linkDocument.Title;
				text = Path.GetFileNameWithoutExtension(text);
				list.Add(text);
				List<ViewPlan> allFloorViewPlan = FloorSelectManager.GetAllFloorViewPlan(linkDocument);
				List<ViewPlan> singleFloorViewPlan = this.GetSingleFloorViewPlan(linkDocument, allFloorViewPlan);
				int num = 0;
				int num2 = 0;
				using (List<ViewPlan>.Enumerator enumerator2 = singleFloorViewPlan.GetEnumerator())
				{
					while (enumerator2.MoveNext())
					{
						if (Geometry.LessThan(enumerator2.Current.GenLevel.Elevation, 0.0))
						{
							num2++;
						}
						else
						{
							num++;
						}
					}
				}
				string item;
				if (num2 > 0)
				{
					item = num.ToString() + "\\-" + num2.ToString();
				}
				else
				{
					item = num.ToString() + "\\" + num2.ToString();
				}
				list.Add(item);
				list.Add(this.GetBuildingHeight(this.m_doc).ToString("0.00"));
				List<ViewPlan> areaViewPlan = this.GetAreaViewPlan(linkDocument);
				double num3 = 0.0;
				double num4 = 0.0;
				foreach (ViewPlan viewPlan in areaViewPlan)
				{
					if (Geometry.LessThan(viewPlan.GenLevel.Elevation, 0.0))
					{
						num4 += UnitConvert.AreaConverFromAPI(this.m_doc, this.GetAreaOfCurAreaViewPlan(this.m_doc, viewPlan));
					}
					else
					{
						num3 += UnitConvert.AreaConverFromAPI(this.m_doc, this.GetAreaOfCurAreaViewPlan(this.m_doc, viewPlan));
					}
				}
				list.Add(num3.ToString("0.00"));
				list.Add(num4.ToString("0.00"));
				list.Add((num3 + num4).ToString("0.00"));
				this.m_lstLstData.Add(list);
			}
		}

		private double GetBuildingHeight(Autodesk.Revit.DB.Document doc)
		{
			double num = 0.0;
			List<Level> sortLevels = FloorSelectManager.GetSortLevels(doc, double.MinValue, double.MaxValue);
			List<Wall> list = new List<Wall>();
			for (int i = sortLevels.Count - 1; i >= 0; i--)
			{
				List<ViewPlan> curElevationViewPlans = this.GetCurElevationViewPlans(doc, sortLevels[i].Elevation);
				if (curElevationViewPlans.Count > 0)
				{
					for (int j = 0; j < curElevationViewPlans.Count; j++)
					{
						ViewPlan viewPlan = curElevationViewPlans[j];
						ElementId elementId = viewPlan.GetUnderLayParameter().AsElementId();
						Transaction transaction = new Transaction(this.m_doc, "ChangeBaseLine");
						transaction.Start();
						viewPlan.GetUnderLayParameter().Set(ElementId.InvalidElementId);
						transaction.Commit();
						OutWallFilter.Search(this.m_doc, viewPlan.Id, ref list, false, true);
						transaction.Start();
						viewPlan.GetUnderLayParameter().Set(elementId);
						transaction.Commit();
					}
					if (list.Count > 0)
					{
						break;
					}
				}
			}
			foreach (Wall elem in list)
			{
				double num2 = 0.0;
				ElementId elementId2 = elem.GetParameter(BuiltInParameter.WALL_HEIGHT_TYPE).AsElementId();
				Level level = doc.GetElement(elementId2) as Level;
				if (level == null)
				{
					ElementId elementId3 = elem.GetParameter(BuiltInParameter.WALL_BASE_CONSTRAINT).AsElementId();
					Level level2 = doc.GetElement(elementId3) as Level;
					if (level2 != null)
					{
						double num3 = elem.GetParameter(BuiltInParameter.WALL_USER_HEIGHT_PARAM).AsDouble();
						num2 = level2.Elevation + num3;
					}
				}
				else
				{
					num2 = level.Elevation;
				}
				if (Geometry.LessThan(num, num2))
				{
					num = num2;
				}
			}
			return UnitConvert.CovertFromAPI((Autodesk.Revit.DB.DisplayUnitType)0, num);
		}

		private List<ViewPlan> GetCurElevationViewPlans(Autodesk.Revit.DB.Document doc, double dElevation)
		{
			List<ViewPlan> list = new List<ViewPlan>();
			foreach (ViewPlan viewPlan in FloorSelectManager.GetAllFloorViewPlan(doc))
			{
				if (Geometry.IsEqual(dElevation, viewPlan.GenLevel.Elevation))
				{
					list.Add(viewPlan);
					break;
				}
			}
			return list;
		}

		private List<RevitLinkInstance> GetAllRevitLinkInstancesInDoc()
		{
			IEnumerable<ElementId> enumerable = new FilteredElementCollector(this.m_doc).OfClass(typeof(RevitLinkInstance)).ToElementIds();
			List<RevitLinkInstance> list = new List<RevitLinkInstance>();
			foreach (ElementId elementId in enumerable)
			{
				Element element = this.m_doc.GetElement(elementId);
				if (!(element.GetType() != typeof(RevitLinkInstance)))
				{
					RevitLinkInstance revitLinkInstance = element as RevitLinkInstance;
					if (revitLinkInstance != null)
					{
						list.Add(revitLinkInstance);
					}
				}
			}
			return list;
		}

		private List<ViewPlan> GetSingleFloorViewPlan(Autodesk.Revit.DB.Document doc, List<ViewPlan> lstViewPlan)
		{
			List<ViewPlan> list = new List<ViewPlan>();
			List<Level> sortLevels = FloorSelectManager.GetSortLevels(doc, double.MinValue, double.MaxValue);
			for (int i = 0; i < sortLevels.Count; i++)
			{
				for (int j = 0; j < lstViewPlan.Count; j++)
				{
					if (Geometry.IsEqual(sortLevels[i].Elevation, lstViewPlan[j].GenLevel.Elevation))
					{
						list.Add(lstViewPlan[j]);
						break;
					}
				}
			}
			return list;
		}

		private List<ViewPlan> GetAreaViewPlan(Autodesk.Revit.DB.Document doc)
		{
			List<ViewPlan> list = new List<ViewPlan>();
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(ViewPlan)))
			{
				ViewPlan viewPlan = element as ViewPlan;
				if (viewPlan != null && (int)viewPlan.ViewType == 116)
				{
					list.Add(viewPlan);
				}
			}
			return list;
		}

		private double GetAreaOfCurAreaViewPlan(Autodesk.Revit.DB.Document doc, ViewPlan viewPlan)
		{
			double result = 0.0;
			foreach (Element element in new FilteredElementCollector(doc, viewPlan.Id).OfClass(typeof(SpatialElement)))
			{
				Area area = element as Area;
				if (area != null && area.AreaScheme.Name == "总建筑面积")
				{
					result = area.Area;
					break;
				}
			}
			return result;
		}

		private bool SetDataToGrid()
		{
			if (this.m_lstLstData.Count <= 0 || this.m_grid == null)
			{
				YJKMessageBox.Show("没有统计数据");
				return false;
			}
			this.m_grid.Range(3, 1, this.m_grid.Rows - 1, this.m_grid.Cols - 1).DeleteByRow();
			this.m_grid.Cell(1, 1).Text = this.m_gridSetInfo.GridName;
			this.m_grid.Cell(1, 1).FontSize = this.m_gridSetInfo.TitleFontSize;
			int num = 3;
			int count = this.m_lstLstData.Count;
			if (count == 0)
			{
				YJKMessageBox.Show("没有找到统计数据");
				return false;
			}
			this.m_grid.Rows = num + count + 1;
			double num2 = 0.0;
			double num3 = 0.0;
			double num4 = 0.0;
			for (int i = 0; i < this.m_lstLstData.Count; i++)
			{
				for (int j = 0; j < this.m_lstLstData[i].Count; j++)
				{
					if (j == 0)
					{
						this.m_grid.Cell(num, j + 1).Text = (i + 1).ToString() + "#";
					}
					else
					{
						this.m_grid.Cell(num, j + 1).Text = this.m_lstLstData[i][j];
					}
					if (j == 4)
					{
						num2 += Convert.ToDouble(this.m_lstLstData[i][j]);
					}
					else if (j == 5)
					{
						num3 += Convert.ToDouble(this.m_lstLstData[i][j]);
					}
					else if (j == 6)
					{
						num4 += Convert.ToDouble(this.m_lstLstData[i][j]);
					}
					this.m_grid.Cell(num, j + 1).Alignment = AlignmentEnum.CenterCenter;
				}
				num++;
			}
			this.m_grid.Cell(num, 1).Text = "合计";
			this.m_grid.Range(num, 1, num, 2).Merge();
			this.m_grid.Cell(num, 5).Text = num2.ToString("0.00");
			this.m_grid.Cell(num, 6).Text = num3.ToString("0.00");
			this.m_grid.Cell(num, 7).Text = num4.ToString("0.00");
			this.m_grid.Range(num, 1, num, 7).Alignment = AlignmentEnum.CenterCenter;
			this.m_grid.Range(1, 1, this.m_grid.Rows - 1, this.m_grid.Cols - 1).WrapText = true;
			this.m_grid.Range(2, 1, this.m_grid.Rows - 1, this.m_grid.Cols - 1).FontName = this.m_gridSetInfo.FontName;
			this.m_grid.Range(2, 1, this.m_grid.Rows - 1, this.m_grid.Cols - 1).FontSize = this.m_gridSetInfo.FontSize;
			for (int k = 1; k < this.m_grid.Rows; k++)
			{
				this.m_grid.Row(k).AutoFit();
			}
			if (!this.m_gridSetInfo.SetColWidth)
			{
				for (int l = 0; l < this.m_grid.Cols; l++)
				{
					this.m_grid.Column(l).AutoFit();
				}
			}
			this.m_grid.Range(1, 1, this.m_grid.Rows - 1, this.m_grid.Cols - 1).set_Borders(EdgeEnum.Outside, LineStyleEnum.Thick);
			this.m_grid.Range(1, 1, this.m_grid.Rows - 1, this.m_grid.Cols - 1).set_Borders(EdgeEnum.Inside, LineStyleEnum.Thin);
			return true;
		}

        private FlexCell.Grid m_grid;

		private Document m_doc;

		private GridSetCommonInfo m_gridSetInfo;

		private List<List<string>> m_lstLstData = new List<List<string>>();
	}
}
